package com.example.cash.craft.security;

import com.example.cash.craft.dao.persist.repository.IUserRepository;
import com.example.cash.craft.exception.ServiceException;
import com.example.cash.craft.pojo.core.CurrentPrincipal;
import com.example.cash.craft.pojo.param.UserLoginParam;
import com.example.cash.craft.pojo.vo.UserLoginResultVO;
import com.example.cash.craft.web.StateCode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;

/**
 * 认证中心业务类
 */
@Service
@Transactional
public class PassportService {

    @Autowired
    private IUserRepository userRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;

    public CurrentPrincipal login(UserLoginParam param) {
        String username = param.getUsername();
        UserLoginResultVO loginResult = userRepository.selectByUsername(username);
        if (loginResult == null) {
            throw new ServiceException(StateCode.ERROR_UNAUTHORIZED, "用户名或密码错误（用户名不存在）");
        }

        if (!passwordEncoder.matches(param.getPassword(), loginResult.getPassword())) {
            throw new ServiceException(StateCode.ERROR_UNAUTHORIZED, "用户名或密码错误（密码不匹配）");
        }

        CurrentPrincipal currentPrincipal = new CurrentPrincipal();
        BeanUtils.copyProperties(loginResult, currentPrincipal);

        ArrayList<GrantedAuthority> authorities = new ArrayList<>();
        if (currentPrincipal.getIsAdmin() == 1) {
            authorities.add(() -> "ROLE_ADMIN");
        }

        Authentication authentication = new UsernamePasswordAuthenticationToken(currentPrincipal, null, authorities);
        SecurityContext securityContext = SecurityContextHolder.getContext();
        securityContext.setAuthentication(authentication);

        return currentPrincipal;
    }

    public void logout() {
        SecurityContextHolder.clearContext();
    }

}
